package cmd

import (
	"fmt"
	"gitee.com/maomaomaoge/go-utils/buff"
	"io"
	"log"
	"net"
	"os"
	"strings"
	"time"

	"github.com/spf13/cobra"
)

// serveCmd represents the serve command
var serveCmd = &cobra.Command{
	Use:   "serve [kind]",
	Short: "serve tcp",
	Long: `serve tcp
用于建立简单的文件传输`,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 0 {
			Ftp("")
		} else {
			Ftp(args[0])
		}
	},
}

func init() {
	rootCmd.AddCommand(serveCmd)
}

func Ftp(port string)  {
	if port == "" {
		port = "5213"
	}
	ln, err := net.Listen("tcp", ":" + port)
	if err != nil {
		log.Fatalln(err)
	}

	fmt.Println("tcp服务: ", port)


	for {
		conn, err := ln.Accept()
		fmt.Println("收到数据")
		if err != nil {
			log.Println(err)
			continue
		}

		now := time.Now()

		// 第一次读取消息字节数
		data := make([]byte, 4)
		_, err = conn.Read(data)
		if err != nil {
			log.Println(err)
			continue
		}
		buf := buff.NewBufferBytes(data)
		allDataLen := buf.Int()
		fmt.Println("总大小:/mb ", float64(allDataLen) / 1024 / 1024)

		// 第一次读取文件名的字节数
		data = make([]byte, 4)
		_, err = conn.Read(data)
		if err != nil {
			log.Println(err)
			continue
		}
		buf = buff.NewBufferBytes(data)
		fileNameByte := buf.Int()

		// 解析文件名字
		data = make([]byte, fileNameByte)
		_, err = conn.Read(data)
		if err != nil {
			log.Println(err)
			continue
		}
		fileNameSlice := strings.Split(strings.ReplaceAll(string(data),`\`, `/`) , `/`)
		fileName := fileNameSlice[len(fileNameSlice) - 1]
		fmt.Println("解析的文件名字为: ", fileName)

		os.RemoveAll(fileName)
		f, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_APPEND, os.ModePerm)
		if err != nil {
			log.Println(err)
			continue
		}

		var curByte int
		for {
			// todo: 可以尝试每一次大点字节的读取
			tmpData := make([]byte, 1024 * 1024 * 5)
			read, err := conn.Read(tmpData)
			if err != nil || err == io.EOF {
				break
			}

			f.Write(tmpData[:read])
			f.Seek(1, read)
			curByte += read
			fmt.Println("当前进度:% ", float64(curByte) / float64(allDataLen) * 100)
		}

		fmt.Println("上传完成")
		f.Close()

		fmt.Println("文件总大小:/mb ", float64(allDataLen) / 1024 / 1024)
		fmt.Println("总用时: ", time.Since(now).String())

		fmt.Println("平均速度:/mb/s ", float64(allDataLen) / 1024 / 1024 / time.Since(now).Seconds())
	}
}
